#include "..\\include\Lib_Clara.h"
#include "..\\include\Dir.h"
#include "..\\include\cfg_items.h"
#include "config_data.h"
#include "conf_loader.h"
#include "skd.h"


#define DESKBAR_RUN_GUI_EVENT         0x3010
#define DESKBAR_REINIT_EVENT          0x3012
#define DESKBAR_SKINEDIT_EDIT_MODE    0x3013
#define DESKBAR_CHANGESKIN_EVENT      0x3014
#define MUSICWIDGET_GOT_FOCUS         0x3015
#define MUSICWIDGET_LOST_FOCUS        0x3016
#define SELECTOR_ICON 10
#define BG_ICON 11

//#define DB3350

#ifndef DB3350
#define _GC_PutChar(_imgID_,_x_,_y_) GC_PutChar(gc,_x_,_y_,0,0,_imgID_)
#endif

#define Dir(__X__) skd->direction==__X__
#define COPYRIGHT_STR L"Deskbar v3.33\n (c)mc_kibel\n(r) KrasH\nJasiek (db3150v1 drawing)\nPloik, BigHercules, MoneyMaster (bookman mod)"

typedef struct
{
  BOOK * book;
}MSG;

typedef struct _MyBOOK : BOOK
{
  GUI_LIST *guilist;
}MyBOOK;

void (*SIonRedraw)(DISP_OBJ *,int r1,int r2,int r3);
void ParseSKD (void);
void SoftkeyRedraw(DISP_OBJ *DO,int a,int b,int c);

GC * gc;
DISP_OBJ *_do;
DISP_OBJ *_sk;
DISP_DESC *Softkey_DD;
DISP_OBJ_ONREDRAW_METHOD Softkey_DefaultRedraw;
MyBOOK * myBook;
u16 ScrollTimer;
POINT selector_pos;

int pos = 1;
int loaded_correctly = 0;
int MainInputLastLen = 0;
int hidden = 0;
int scrtmrwrk = 0;
int prev_key,next_key;
int t_count = 0;
int bar_width = 0;
int bar_height = 0;
int focused = 1;

wchar_t *imgName[]={L"Icon1.png",L"Icon2.png",L"Icon3.png",L"Icon4.png",L"Icon5.png",L"Icon6.png",L"Icon7.png",L"Icon8.png",L"Icon9.png",L"Icon10.png",L"selector.png",L"bg.png"};
wchar_t imgID[]={0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
wchar_t *imgName_sel[]={L"Icon1sel.png",L"Icon2sel.png",L"Icon3sel.png",L"Icon4sel.png",L"Icon5sel.png",L"Icon6sel.png",L"Icon7sel.png",L"Icon8sel.png",L"Icon9sel.png",L"Icon10sel.png"};
wchar_t imgID_sel[]={0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
wchar_t LINK_1[0x1F],LINK_2[0x1F],LINK_3[0x1F],LINK_4[0x1F],LINK_5[0x1F],LINK_6[0x1F],LINK_7[0x1F],LINK_8[0x1F],LINK_9[0x1F],LINK_10[0x1F];
wchar_t const* shortcuts[] = {LINK_1,LINK_2,LINK_3,LINK_4,LINK_5,LINK_6,LINK_7,LINK_8,LINK_9,LINK_10};
wchar_t CONFIG_NAME[]=L"Config.skd";
wchar_t SLASH[]=L"/";

typedef struct
{
  int deskbar_old_y;
  int deskbar_old_x;
  int deskbar_x;
  int deskbar_y;
  int xsize;
  int ysize;
  int softused;
  int bg_x;
  int bg_y;
  wchar_t skinpath[256];
}DESKBAR_DATA;

DESKBAR_DATA * desk_data;
SKD *skd;

/*
#ifdef DB3350
void _GC_PutChar(wchar_t imgID, int x, int y)
{
  int img = imgID|0x78000000;
  DrawString( img,0, x, y, 0,0,0,0, 0xFFFFFF00, 0xFFFFFF00 );
}
#endif
*/

int isA2DeskbarBook(BOOK * book)
{
  if(!strcmp(book->xbook->name,"Deskbar")) 
    return 1;
  return 0;
}

int IconIDname2ID (wchar_t *idname)
{
  int nIconID;
  iconidname2id( idname, -1, &nIconID );
  return nIconID;
}

void InitImages(void)
{
  int i=0;
  for (;i<sizeof(imgID)/2;i++) ImageID_Get(desk_data->skinpath,imgName[i],&imgID[i]);
  i = 0;
  for (;i<sizeof(imgID_sel)/2;i++) ImageID_Get(desk_data->skinpath,imgName_sel[i],&imgID_sel[i]);
  bar_width = 0;
  i = 0;
  for (;i < skd->items ; i++) bar_width += GetImageWidth(imgID[i]);
  bar_height = 0;
  i = 0;
  for (;i < skd->items ; i++) bar_height += GetImageHeight(imgID[i]);
}

void DestroyImages(void)
{
  int i=0;
  for (;i<sizeof(imgID)/2;i++) ImageID_Free(imgID[i]);
  i = 0;
  for (;i<sizeof(imgID_sel)/2;i++) ImageID_Free(imgID_sel[i]);
}

int _MainInput_getVisible( GUI * g )
{
  char c;
  DISP_OBJ* dispobj = GUIObject_GetDispObject( g ); 
  c = DispObject_GetVisible( dispobj );
  if (MainInputLastLen == 1)
  {
    MainInputLastLen = 0;
    c = 1;
  }
  return (c);
}

int RunSkinEdit (void)
{
  FSTAT _fstat;
  wchar_t skineditpath[256];
  if(fstat(GetDir(DIR_ELFS|MEM_INTERNAL),L"SkinEdit.elf",&_fstat)==0)
    wstrcpy(skineditpath,GetDir(DIR_ELFS|MEM_INTERNAL));
  else if(fstat(GetDir(DIR_ELFS|MEM_EXTERNAL),L"SkinEdit.elf",&_fstat)==0)
    wstrcpy(skineditpath,GetDir(DIR_ELFS|MEM_EXTERNAL));
  else
  {
    MessageBox(0x6FFFFFFF, STR("SkinEdit.elf not found!"), 0, 1 ,0, 0);
    return (0);
  }
  wstrcat(skineditpath,L"/SkinEdit.elf");
  elfload(skineditpath,(void*)desk_data->skinpath,(void*)CONFIG_NAME,0);
  UI_Event(DESKBAR_SKINEDIT_EDIT_MODE);
  return (1);
}

int RunBCFGEdit (void)
{
  FSTAT _fstat;
  wchar_t bcfgpath[256];
  if(fstat(GetDir(DIR_ELFS|MEM_INTERNAL),L"BcfgEdit.elf",&_fstat)==0)
    wstrcpy(bcfgpath,GetDir(DIR_ELFS|MEM_INTERNAL));
  else if(fstat(GetDir(DIR_ELFS|MEM_EXTERNAL),L"BcfgEdit.elf",&_fstat)==0)
    wstrcpy(bcfgpath,GetDir(DIR_ELFS|MEM_EXTERNAL));
  else
  {
    MessageBox(0x6FFFFFFF, STR("BcfgEdit.elf not found!"), 0, 1 ,0, 0);
    return (0);
  }
  wstrcat(bcfgpath,L"/BcfgEdit.elf");
  elfload(bcfgpath,(void*)successed_config_path,(void*)successed_config_name,0);
  return (1);
}

void SetSettings (void)
{
  pos = 1;
  DestroyImages();
  InitImages();
}

void ReInit (void)
{
  InitConfig();
  selector_pos.x = 0;
  selector_pos.y = 0;
  ParseSKD();
  SetSettings ();
}

void OnSelectGui( BOOK* bk, GUI* )
{
  MyBOOK* mbk = (MyBOOK*) bk;
  int item = ListMenu_GetSelectedItem( mbk->guilist );
  switch (item)
  {
  case 0:
    ReInit();
    MessageBox(0x6FFFFFFF,STR("Reloaded!"),0, 1 ,0,0);
    break;
  case 1:
    RunBCFGEdit();
    break;
  case 2:
    RunSkinEdit();
    break;
  case 3:
    FreeBook(FindBook(isA2DeskbarBook));
    break;
  default:
    break;
  }
}

int onLBMessage( GUI_MESSAGE* msg )
{
  MyBOOK* myBook = (MyBOOK*) GUIonMessage_GetBook( msg );
  switch( GUIonMessage_GetMsg( msg ) )
  {
  case 1:
    int item = GUIonMessage_GetCreatedItemIndex( msg );
    if (item == 0)
    {
      GUIonMessage_SetMenuItemText( msg, STR("Reload elf data") );
      GUIonMessage_SetMenuItemIcon( msg, 0, IconIDname2ID (L"SYNC_MENU_ICN") );
    }
    else if (item == 1)
    {
      GUIonMessage_SetMenuItemText( msg, STR("Configure elf") );
      GUIonMessage_SetMenuItemIcon( msg, 0, IconIDname2ID(L"RN_SHORTCUT_LIST_SETTINGS_ICN") );
    }
    else if (item == 2)
    {
      GUIonMessage_SetMenuItemText( msg, STR("Edit skin") );
      GUIonMessage_SetMenuItemIcon( msg, 0, IconIDname2ID(L"NT_NOTES_MENU_ICN") );
    }
    else if (item == 3)
    {
      GUIonMessage_SetMenuItemText( msg, STR("Close elf") );
      GUIonMessage_SetMenuItemIcon( msg, 0, IconIDname2ID(L"CALE_TODOS_MENU_ICN") );
    }
    break;
  }
  return 1;
}

void OnBackGui( BOOK* bk, GUI* )
{
  MyBOOK * mbk = (MyBOOK*)bk;
  BookObj_Hide(mbk,0);
  GUIObject_Destroy( mbk->guilist );
  mbk->guilist = 0;  
}

GUI_LIST* CreateGuiList( MyBOOK* bk, int set_focus )
{
  GUI_LIST* lo;
  lo = CreateListMenu( bk, 0 );
  bk->guilist = lo;
  GUIObject_SetTitleText( lo, Str2ID(L"Deskbar settings",0,SID_ANY_LEN) );
  ListMenu_SetItemCount( lo, 4 );
  ListMenu_SetOnMessage( lo, onLBMessage );
  ListMenu_SetCursorToItem( lo, set_focus );
  ListMenu_SetItemStyle( lo, 0 );
  ListMenu_SetItemTextScroll( lo, 1 );
  GUIObject_SoftKeys_SetAction( lo, ACTION_BACK, OnBackGui );
  GUIObject_SoftKeys_SetAction( lo, ACTION_LONG_BACK, OnBackGui );
  GUIObject_SoftKeys_SetAction( lo, ACTION_SELECT1, OnSelectGui );
  GUIObject_Show( lo );
  return lo;
};

void CreateConfigGUI (void)
{
  myBook->guilist = CreateGuiList( myBook, 0 );
  if (Display_GetTopBook(0) != FindBook(isA2DeskbarBook))
  {
    BookObj_SetFocus (FindBook(isA2DeskbarBook),0);
  }
}

void Invalidate (void)
{
  DispObject_InvalidateRect(_do,0);
  if (desk_data->softused) DispObject_InvalidateRect(_sk,0);
}



void OptimizedRefreshTimer (u16 unk , void * data)
{
  Invalidate();
  t_count++;
  if (t_count < 20)
  {
    Timer_ReSet(&ScrollTimer,10,OptimizedRefreshTimer,0);
  }
  else
  {
    scrtmrwrk = 0;
    t_count = 0;
    Timer_Kill(&ScrollTimer);
  }
}

void Select (void)
{
  int link_type;
  switch (pos)
  {
  case 1:
    link_type = skd->l1mode;
    break;
  case 2:
    link_type = skd->l2mode;
    break;
  case 3:
    link_type = skd->l3mode;
    break;
  case 4:
    link_type = skd->l4mode;
    break;
  case 5:
    link_type = skd->l5mode;
    break;
  case 6:
    link_type = skd->l6mode;
    break;
  case 7:
    link_type = skd->l7mode;
    break;
  case 8:
    link_type = skd->l8mode;
    break;
  case 9:
    link_type = skd->l9mode;
    break;
  case 10:
    link_type = skd->l10mode;
    break;
  }
  if (link_type == LINK_MENU)
    Shortcut_Run((wchar_t*)shortcuts[pos-1]);
  else if (link_type == LINK_APP)
  {
    char sp_flag;
    debug_printf ("\n -> Deskbar: starting JAVA application. AppID = %d \n", shortcuts[pos-1][0]+0x10000);
    REQUEST_UI_OAF_START_APPLICATION( ASYNC, shortcuts[pos-1][0]+0x10000, &sp_flag );
  }
  else if (link_type == LINK_ELF)
  {
    FSTAT fst;
    wchar_t smth[256];
    if (fstat( GetDir(DIR_ELFS | MEM_INTERNAL), shortcuts[pos-1], &fst ) == 0)
    {
      snwprintf (smth,255,L"%ls/%ls",GetDir(DIR_ELFS | MEM_INTERNAL),shortcuts[pos-1]);
      elfload(smth,0,0,0);
    }
    else if (fstat( GetDir(DIR_ELFS | MEM_EXTERNAL), shortcuts[pos-1], &fst ) == 0)
    {
      snwprintf (smth,255,L"%ls/%ls",GetDir(DIR_ELFS | MEM_EXTERNAL),shortcuts[pos-1]);
      elfload(smth,0,0,0);
    }
  }
}

void OnKey (int key, int mode)
{
  if (key==prev_key && mode==KBD_SHORT_RELEASE)
  {
    if (pos>1)
      pos--;
    else
      pos=skd->items;
  }
  else if (key==next_key && mode==KBD_SHORT_RELEASE)
  {
    if (pos<skd->items)
      pos++;
    else
      pos = 1;
  }
  else if (key==select_key && mode==select_mode)
    Select();
}

void Refresh (void)
{
  if (scrtmrwrk == 0)
  {
    ScrollTimer = Timer_Set(10,OptimizedRefreshTimer,0);
    scrtmrwrk++;
  }
}

void CheckShowHide (void)
{
  if (hidden == 1)
  {
    if (Dir(DIRECTION_LEFT) && (skd->orientation==HORIZONTAL ? desk_data->deskbar_x > 0 - bar_width : desk_data->deskbar_x > 0 - GetImageWidth( imgID[pos-1] )))
    {
      desk_data->deskbar_x -= skd->speed;
      Refresh();
    }
    else if (Dir(DIRECTION_RIGHT) && desk_data->deskbar_x < desk_data->xsize)
    {
      desk_data->deskbar_x += skd->speed;
      Refresh();
    }
    else if (Dir(DIRECTION_UP) && (skd->orientation==HORIZONTAL ? desk_data->deskbar_y > 0 - GetImageWidth( imgID[pos-1] ) : desk_data->deskbar_y > 0 - bar_height))
    {
      desk_data->deskbar_y -= skd->speed;
      Refresh();
    }
    else if (Dir(DIRECTION_DOWN) && desk_data->deskbar_y < desk_data->ysize)
    {
      desk_data->deskbar_y += skd->speed;
      Refresh();
    }
  }
  else
  {
    if (Dir(DIRECTION_LEFT) && desk_data->deskbar_old_x > desk_data->deskbar_x)
    {
      desk_data->deskbar_x += skd->speed;
      Refresh();
    }
    else if (Dir(DIRECTION_RIGHT) && desk_data->deskbar_old_x < desk_data->deskbar_x)
    {
      desk_data->deskbar_x -= skd->speed;
      Refresh();
    }
    else if (Dir(DIRECTION_UP) && desk_data->deskbar_old_y > desk_data->deskbar_y)
    {
      desk_data->deskbar_y += skd->speed;
      Refresh();
    }
    else if (Dir(DIRECTION_DOWN) && desk_data->deskbar_old_y < desk_data->deskbar_y)
    {
      desk_data->deskbar_y -= skd->speed;
      Refresh();
    }
  }
}

int WidgetKey (int key, int r1, int mode)
{
  if (focused == 1)
  {
    if (Display_GetTopBook(0) == Find_StandbyBook())
    {
      if (MainInputLock == 1)
      {
        if (_MainInput_getVisible(SBY_GetMainInput(Find_StandbyBook()))==0)
        {
          if (key==rungui_key && mode==rungui_mode)
            CreateConfigGUI();
          if (key==anim_key && mode==anim_mode)
          {
            if (hidden == 0) hidden = 1;
            else hidden = 0;
          }
          if (hidden == 0) OnKey (key,mode);
        }
        else
          MainInputLastLen = MainInput_strlen( SBY_GetMainInput(Find_StandbyBook()) );
      }
      else
      {
        if (key==rungui_key && mode==rungui_mode)
          CreateConfigGUI();
        if (key==anim_key && mode==anim_mode)
        {
          if (hidden == 0) hidden = 1;
          else hidden = 0;
        }
        if (hidden == 0) OnKey (key,mode);
      }
      Invalidate();
    }
  }
  return 0;
}

void Redraw (int xp, int yp)
{
  if (skd->skin_type == OLDSKIN)
    _GC_PutChar(imgID[pos-1],xp,yp);
  else
  {
    if (skd->xhack != ENABLED)
    {
      if (skd->bg_enabled == 1 && hidden == 0) _GC_PutChar(imgID[BG_ICON], desk_data->bg_x, desk_data->bg_y);
      if (skd->orientation == HORIZONTAL)
      {
        selector_pos.x = xp + GetImageWidth(imgID[SELECTOR_ICON]) * (pos-1) + (pos == 1 ? 0 : skd->spacing * (pos-1));
        selector_pos.y = yp;
        _GC_PutChar(imgID[SELECTOR_ICON], selector_pos.x, selector_pos.y);
        for (int i = 0 ; i < skd->items ; i++)
        {
          if (i == (pos-1) && skd->sel_icon_enabled == 1)
            _GC_PutChar(imgID_sel[i], xp + GetImageWidth(imgID_sel[i]) * i + (i == 0 ? 0 : skd->spacing * i), yp);
          else
            _GC_PutChar(imgID[i], xp + GetImageWidth(imgID[i]) * i + (i == 0 ? 0 : skd->spacing * i), yp);
        }
        if (selector_pos.x >= (desk_data->xsize - GetImageWidth(imgID[SELECTOR_ICON]))   && hidden == 0)
        {
          desk_data->deskbar_x -= skd->speed;
          Refresh();
        }
        if (selector_pos.x < 0   && hidden == 0)
        {
          desk_data->deskbar_x += skd->speed;
          Refresh();
        }
      }
      else
      {
        selector_pos.x = xp;
        selector_pos.y = yp + GetImageHeight(imgID[SELECTOR_ICON]) * (pos-1) + (pos == 1 ? 0 : skd->spacing * (pos-1));
        _GC_PutChar(imgID[SELECTOR_ICON], selector_pos.x, selector_pos.y);
        for (int i = 0 ; i < skd->items ; i++) 
        {
          if (i == (pos-1) && skd->sel_icon_enabled == 1)
            _GC_PutChar(imgID_sel[i], xp, yp + GetImageHeight(imgID_sel[i]) * i + (i == 0 ? 0 : skd->spacing * i));
          else
            _GC_PutChar(imgID[i], xp, yp + GetImageHeight(imgID[i]) * i + (i == 0 ? 0 : skd->spacing * i));
        }
        if (selector_pos.y >= desk_data->ysize - StatusbarSize - SoftSize - GetImageHeight(imgID[10])   && hidden == 0)
        {
          desk_data->deskbar_y -= skd->speed;
          Refresh();
        }
        if (selector_pos.y < 0   && hidden == 0)
        {
          desk_data->deskbar_y += skd->speed;
          Refresh();
        }
      }
    }
    else //Super X-Hack enabled :D [Smooth-6 Skins]
    {
      selector_pos.y = yp;
      if (skd->bg_enabled == 1 && hidden == 0) _GC_PutChar(imgID[BG_ICON], desk_data->bg_x, desk_data->bg_y);
      if (selector_pos.x < 40 * (pos-1) || selector_pos.x < 0)
      {
        if (hidden == 0)
        {
          selector_pos.x += 10;
          Refresh();
        }
      }
      else if (selector_pos.x > 40 * (pos-1) || selector_pos.x > desk_data->xsize - GetImageWidth(imgID[SELECTOR_ICON]))
      {
        if (hidden == 0)
        {
          selector_pos.x -= 10;
          Refresh();
        }
      }
      _GC_PutChar(imgID[SELECTOR_ICON], selector_pos.x, selector_pos.y);
      for (int i = 0 ; i < 6 ; i++)
      {
        if (i == (pos-1) && skd->sel_icon_enabled == 1) _GC_PutChar(imgID_sel[i], GetImageWidth(imgID_sel[i]) * i, yp);
        else _GC_PutChar(imgID[i], GetImageWidth(imgID[i]) * i, yp);
      }
    }
  }
  CheckShowHide();
}

void DISP_OnRedraw(DISP_OBJ* DO,int a,int b,int c) 
{
  if (SIonRedraw) SIonRedraw(DO,a,b,c); 
  Redraw (desk_data->deskbar_x,desk_data->deskbar_y); 
}
  
void elf_exit(void)
{
  kill_data(&ELF_BEGIN, (void(*)(void*))mfree_adr());
}

void Send_REDRAW_RELEASE()
{
  REDRAW_RELEASE_MESSAGE * sbm= new REDRAW_RELEASE_MESSAGE;
  memset(sbm,0,sizeof(REDRAW_RELEASE_MESSAGE));
  sbm->SB_OldOnRedraw=SIonRedraw;
    sbm->SB_NewOnRedraw=DISP_OnRedraw;
  if (desk_data->softused == 1)
  {
    sbm->SK_OldOnRedraw=Softkey_DefaultRedraw;
    sbm->SK_NewOnRedraw=SoftkeyRedraw;
  }
  UI_Event_wData(SBY_REDRAW_RELEASE_EVENT ,sbm,(void (*)(void*))mfree_adr());
}

static int TerminateElf(void * ,BOOK *book)
{
  skd->affect_softkeys = 0;
  DispObject_InvalidateRect(_sk,0);
  FreeBook(book);
  return(1);
}

static int ShowAuthorInfo(void *mess ,BOOK *book)
{
  MSG * msg = (MSG *)mess;
  MessageBox(0x6FFFFFFF,Str2ID(COPYRIGHT_STR,0,SID_ANY_LEN),0, 1 ,0,msg->book);
  return(1);
}

static int ReconfigElf(void *mess ,BOOK *book)
{
  RECONFIG_EVENT_DATA *reconf=(RECONFIG_EVENT_DATA *)mess;
  int result=0;
  if (wstrcmpi(reconf->path,successed_config_path)==0 && wstrcmpi(reconf->name,successed_config_name)==0)
  {
    InitConfig();
    SetSettings ();
    ParseSKD();
    result=1;
  }
  return(result);
}

int SB_ELF_Killed(void *mess ,BOOK* book)
{
  REDRAW_RELEASE_MESSAGE * sbm=(REDRAW_RELEASE_MESSAGE*)mess;
  REDRAW_RELEASE_MESSAGE *res=0;
  if (sbm->SB_NewOnRedraw==SIonRedraw)
  {
    res=new REDRAW_RELEASE_MESSAGE;
    memcpy(res,sbm,sizeof(REDRAW_RELEASE_MESSAGE));
    if (sbm->SB_OldOnRedraw) SIonRedraw=sbm->SB_OldOnRedraw;
    DISP_DESC_SetOnRedraw(DispObject_GetDESC(_do),DISP_OnRedraw);
    res->SB_NewOnRedraw=DISP_OnRedraw;
    res->SB_OldOnRedraw=0;
  }
  if (sbm->SK_NewOnRedraw==Softkey_DefaultRedraw)
  {
    if (!res)
    {
      res=new REDRAW_RELEASE_MESSAGE;
      memcpy(res,sbm,sizeof(REDRAW_RELEASE_MESSAGE));
    }
    if (sbm->SK_OldOnRedraw) Softkey_DefaultRedraw=sbm->SK_OldOnRedraw;
    res->SK_OldOnRedraw=0;
    res->SK_NewOnRedraw=SoftkeyRedraw;
  }
  if (res)
  {
    UI_Event_wData(SBY_REDRAW_RELEASE_EVENT ,res,(void (*)(void*))mfree_adr());
    return 1;
  }
  return 0;
}

int RunGui (void *mess, BOOK *bk)
{
  CreateConfigGUI();
  return 0;
}

int OnChangeSkin (void *mess, BOOK *bk)
{
  MessageBox(0x6FFFFFFF,STR("Deskbar skin changed."),IconIDname2ID(L"POPUP_THEME_CHANGE_ICN"), 1 ,0,0);
  wchar_t * nskin_path = (wchar_t*)mess;
  int f = _fopen(confpath,L"LastSkin.txt",WA_Write,0x180,0);
  fwrite( f, nskin_path, wstrlen(nskin_path)*2+64 );
  fclose(f);
  wstrcpy (desk_data->skinpath,nskin_path);
  ReInit();
  return 0;
}

int OnReInitEvent (void *mess, BOOK *bk)
{
  ReInit();
  return 0;
}

int onMW_GotFocus (void *mess, BOOK *bk)
{
  focused = 0;
  return 0;
}

int onMW_LostFocus (void *mess, BOOK *bk)
{
  focused = 1;
  return 1;
}

const PAGE_MSG bk_msglst_base[] @ "DYN_PAGE"  = 
{
  MUSICWIDGET_GOT_FOCUS,        onMW_GotFocus,
  MUSICWIDGET_LOST_FOCUS,       onMW_LostFocus,
  DESKBAR_RUN_GUI_EVENT,        RunGui,
  DESKBAR_CHANGESKIN_EVENT,     OnChangeSkin,
  DESKBAR_REINIT_EVENT,         OnReInitEvent,
  SBY_REDRAW_RELEASE_EVENT,     SB_ELF_Killed,
  ELF_TERMINATE_EVENT,          TerminateElf,
  ELF_SHOW_INFO_EVENT,          ShowAuthorInfo,
  ELF_RECONFIG_EVENT,           ReconfigElf,
  NIL_EVENT_TAG,                NULL
};
const PAGE_DESC bk_base = {"StandbyInfo_Base_Page",0,bk_msglst_base};

void SoftkeyRedraw(DISP_OBJ *DO,int a,int b,int c)
{
  if (skd->affect_softkeys == 1)
  {
    if (Display_GetTopBook(0) != Find_StandbyBook())
      Softkey_DefaultRedraw(DO,a,b,c);
    else
      Redraw (desk_data->deskbar_x,desk_data->deskbar_y+SoftSize-desk_data->ysize+StatusbarSize);
  }
  else
    Softkey_DefaultRedraw(DO,a,b,c);
}

void Softkey_SetOnRedraw (void)
{
  _sk=DispObject_SoftKeys_Get();
  Softkey_DefaultRedraw=DispObject_GetOnRedraw(_sk);
  Softkey_DD=DispObject_GetDESC(_sk);
  DISP_DESC_SetOnRedraw(Softkey_DD,SoftkeyRedraw);
}

static void onMyBookClose(BOOK * book)
{
  if (loaded_correctly == 1)
  {
    DISP_DESC_SetOnRedraw(DispObject_GetDESC(_do),SIonRedraw);
    DispObject_InvalidateRect(_do,0);
    if (desk_data->softused == 1)
    {
      DISP_DESC_SetOnRedraw(DispObject_GetDESC(_sk),Softkey_DefaultRedraw);
      DispObject_InvalidateRect(_sk,0);
    }
  }
  if (scrtmrwrk == 1)
    Timer_Kill(&ScrollTimer);
  DestroyImages();
  ModifyKeyHook(WidgetKey,0);
  Send_REDRAW_RELEASE();
  if (desk_data)
    mfree (desk_data);
  mfree (skd);
  SUBPROC(elf_exit);
}

void ParseSKD (void)
{
  memset (skd,0,sizeof(SKD));
  int s;
  FSTAT fst;
  if (fstat( desk_data->skinpath, CONFIG_NAME, &fst ) == 0)
  {
    s=_fopen(desk_data->skinpath,CONFIG_NAME,0x001,0x180,0);
    fread ( s, skd, sizeof(SKD) );
    if ((skd->hdr[0] + skd->hdr[1] + skd->hdr[2]) == (0x53 + 0x4B + 0x44))
    {
      desk_data->deskbar_x = skd->xpos + skd->xplus;
      desk_data->deskbar_y = skd->ypos + skd->yplus;
      desk_data->deskbar_old_y = desk_data->deskbar_y;
      desk_data->deskbar_old_x = desk_data->deskbar_x;
      desk_data->bg_x = skd->bg_xpos + skd->bg_xplus;
      desk_data->bg_y = skd->bg_ypos + skd->bg_yplus;
      if (skd->orientation == HORIZONTAL)
      {
        prev_key = KEY_LEFT;
        next_key = KEY_RIGHT;
      }
      else
      {
        prev_key = KEY_UP;
        next_key = KEY_DOWN;
      }
      if (skd->affect_softkeys == 1 && skd->skin_type == NEWSKIN)
        MessageBox(0x6FFFFFFF,STR("It's recommended to disable drawing on softkeys, it may cause a problems in new skins."),0, 1 ,10000,0);
      if (skd->animated == 1 && skd->direction < 1)
        skd->animated = 0;
      str2wstr( LINK_1, skd->link1 );
      str2wstr( LINK_2, skd->link2 );
      str2wstr( LINK_3, skd->link3 );
      str2wstr( LINK_4, skd->link4 );
      str2wstr( LINK_5, skd->link5 );
      str2wstr( LINK_6, skd->link6 );
      str2wstr( LINK_7, skd->link7 );
      str2wstr( LINK_8, skd->link8 );
      str2wstr( LINK_9, skd->link9 );
      str2wstr( LINK_10, skd->link10 );
      if (skd->affect_softkeys == 1 && desk_data->softused != 1)
      {
        Softkey_SetOnRedraw();
        desk_data->softused = 1;
      }
    }
    else
    {
      MessageBox(0x6FFFFFFF,STR("Loaded .skd file is damaged or doesn't exist!"),0, 1 ,3000,0);
      FreeBook(FindBook(isA2DeskbarBook));
    }
    fclose( s );
  }
}

int main(void)
{
  if (FindBook(isA2DeskbarBook))
  {
    MessageBox(0x6FFFFFFF,STR("Deskbar is already working!"),0, 1 ,0,0);
    return 1;
  }
  InitConfig();
  FSTAT fst;
  myBook = new MyBOOK;
  memset( myBook, 0, sizeof( MyBOOK ) );
  CreateBook(myBook,onMyBookClose,&bk_base,"Deskbar",-1,0);
  desk_data = (DESKBAR_DATA*)malloc(sizeof(DESKBAR_DATA));
  memset (desk_data,0,sizeof(DESKBAR_DATA));
  skd = (SKD*)malloc(sizeof(SKD));
  if (fstat( confpath, L"LastSkin.txt", &fst ) == 0)
  {
    int f = _fopen(confpath,L"LastSkin.txt",WA_Read,0x180,0);
    wchar_t last_skin_name[256];
    fread ( f, last_skin_name, 256 );
    debug_printf ("\n --->>> last skin: %ls \n",last_skin_name);
    wstrcpy (desk_data->skinpath , last_skin_name);
    fclose (f);
  } 
  else
    MessageBox(0x6FFFFFFF,STR("Deskbar loaded. It's probably first run of elf, so you have to set skin now (Click on .skd)"),0, 1 ,0,0);
  desk_data->ysize = Display_GetHeight(0);
  desk_data->xsize = Display_GetWidth(0);
  _do = GUIObject_GetDispObject((GUI*)List_Get(Find_StandbyBook()->xguilist->guilist,0));
  //_do=GUIObject_GetDispObject(SBY_GetStatusIndication(Find_StandbyBook()));
  SIonRedraw=DispObject_GetOnRedraw(_do);
  ModifyKeyHook (WidgetKey,1);
  gc = get_DisplayGC();
  ParseSKD();
  InitImages();
  loaded_correctly = 1;
  DISP_DESC_SetOnRedraw(DispObject_GetDESC(_do),DISP_OnRedraw);
  return 0;
}
